package com.alipay.sofa.demo.db.provider.producer;

import com.alipay.sofa.demo.db.common.tool.ProtostuffUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;

/**
 * @Author Zhang Da
 * @Date 2020/2/17 17:31
 * @Version 1.0
 */
@Component
public class RedisClient {
    private final RedisTemplate<String, String> redisTemplate;

    @Autowired
    public RedisClient(RedisTemplate<String, String> redisTemplate) {
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        this.redisTemplate = redisTemplate;
    }

    /**
     * get cache
     *
     * @param key
     * @param targetClass
     * @param <T>
     * @return
     */
    public <T> T getByProtostuff(final String key, Class<T> targetClass) {
        byte[] result = redisTemplate.execute((RedisCallback<byte[]>) connection -> connection.get(key.getBytes()));
        if (result == null) {
            return null;
        }

        return ProtostuffUtil.deserializer(result, targetClass);
    }

    /**
     * put cache
     *
     * @param key
     * @param obj
     * @param <T>
     * @return
     */
    public <T> void setByProtostuff(String key, T obj, Class<T> targetClass) {
        final byte[] value = ProtostuffUtil.serializer(obj, targetClass);
        redisTemplate.execute((RedisCallback<Void>) connection -> {
            connection.set(key.getBytes(), value);
            return null;
        });
    }

    /**
     * put cache with expire time
     *
     * @param key
     * @param obj
     * @param expireTime 单位: s
     * @param <T>
     */
    public <T> void setWithExpire(String key, T obj, Class<T> targetClass, final long expireTime) {
        final byte[] value = ProtostuffUtil.serializer(obj, targetClass);
        redisTemplate.execute((RedisCallback<Void>) connection -> {
            connection.setEx(key.getBytes(), expireTime, value);
            return null;
        });
    }

    /**
     * 普通缓存获取
     * @param key 键
     * @return 值
     */
    public Object get(String key){
        return key==null?null:redisTemplate.opsForValue().get(key);
    }

    /**
     * 普通缓存放入
     * @param key 键
     * @param value 值
     * @return true成功 false失败
     */
    public boolean set(String key,Object value) {
        try {
            redisTemplate.opsForValue().set(key, (String) value);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public boolean delete(String key){
        return redisTemplate.delete(key);
    }
}

